#ifndef RULE_H_
#define RULE_H_
#include "../global/global_declarations.h"
#include "dictionary.h"

typedef enum RuleType {
	EmptyType,
	CaseSensitiveDictionaryWord,
	CaseInsensitiveDictionaryWord,
	SequenceOfDigits,
	SequenceOfCharacters
} RuleType;

typedef struct RuleElement{
	RuleType rule_type;
	int digit_or_character_bound;
	struct RuleElement* next_element;
}RuleElement;

typedef struct Rule {
	RuleElement* rule_element;
	struct Rule* next_rule;
} Rule;

extern Rule* the_rule;

RuleElement* make_rule_element();
char* go_after_the_digits(char* str);
RuleElement* make_list_element_from_string(String str);
Rule* make_rule();
Rule* make_single_rule_from_string(String str);
Rule* make_rule_list_from_string(String str);
void word_k_for_rule(int64 k, String* dest);
int64 combinatorial(int a, int b);
int64 get_sequenceOfDigits_sum(int n);
int64 get_SequenceOfCharacters_sum(int n);
int64 count_words_in_rule_element(RuleElement* r, Dictionary* d);
Rule* get_the_rule();
int64 count_words_in_whole_rule(Rule* r, Dictionary* d);
void get_word_k_for_single_element(String* dest, int64 k, RuleElement* r, Dictionary* d);
void create_word_k_CaseInsensitiveDictionaryWord(String* dest, int64 k, Dictionary* d);
void create_word_k_SequenceOfCharacters(String* dest, int64 k);
void create_word_k_SequenceOfDigits(String* dest, int64 k);
void choose_case_combination_k(String* dest, int64 k, String* src);
void free_rule(Rule* r);
void free_rule_element(RuleElement* r);
void print_rule_element(RuleElement* r);
void print_rule(Rule* r);
bool validate_rule(char* r);


#endif /* RULE_H_ */
